<?php
declare(strict_types=1);
/**
 * Created by project.
 * User: huanzipap
 * Date: 2023/5/10
 * Time: 11:25
 */
namespace App\Controller\User;

use App\Controller\AppBaseController;
use App\Model\Act;
use App\Model\ActAnswerJoin;
use App\Model\ActAnswerLog;
use App\Model\ActJoin;
use App\Model\ActPrizeGoods;
use App\Model\ActPrizeJoin;
use App\Model\ActRead;
use App\Model\ActSurveyLog;
use App\Model\Notify;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\HttpServer\Annotation\Middleware;
use App\Middleware\WxApiAuth;
use Hyperf\DbConnection\Db;

#[Controller(prefix: 'user')]
#[Middleware(WxApiAuth::class)]
class ActPrizeController extends AppBaseController
{

    /**
     * 抽奖完成任务
     * @param int $act_id
     * @return object
     * @throws \RedisException
     */
    #[RequestMapping(path: 'actPrizeJoin/{act_id}',methods: 'post,get')]
    public function actPrizeJoin(int $act_id): object
    {
        //redis锁名称，写在外面用户异常解锁
        $lockKey = $this->redisPrefix.':'.'prize_lock';
        try{
            //验证用户信息
            $checkInfo = $this->checkUser();
            if($checkInfo['status']==40002) return $this->reMsg->re(10002,$checkInfo['message']);
            $_user = $checkInfo['data'];

            //抽奖活动信息
            $info = Act::where('id',$act_id)->first();
            if(empty($info)) return $this->reMsg->re(10008);
            if($info->type != 3) return $this->reMsg->re(0,'活动类型有误');
            //判断开始时间
            if($info->start_time && time()<strtotime($info->start_time)) return $this->reMsg->re(0,'活动未开始');
            //判断结束时间
            if($info->end_time && time()>strtotime($info->end_time)) return $this->reMsg->re(0,'活动已结束');
            //判断参与人数
            if($info->max_limit>0 && $info->join_count>=$info->max_limit) return $this->reMsg->re(0,'参与人数超过限制');

            //先查询该用户是否已经参与抽奖

            //返回抽奖信息
            $joinWhere['act_id'] = $act_id;
            $joinWhere['uid'] = $_user->id;
            $prizeJoinInfo = ActPrizeJoin::where($joinWhere)->first();
            if($prizeJoinInfo) return $this->reMsg->re(10010);
            //未参与抽奖
            $actInfo = Act::with(['prizeRule'=>function($query){
                $query->selectRaw('id,act_id,rule,percent,template')->first();
            },'prizeGoods'=>function($query){
                $query->selectRaw('id,act_id,type,name,photo,stock')->get();
            }])->where('id',$act_id)->first();

            //验证抽奖奖品和抽奖规则
            if($actInfo->prizeGoods==null || count($actInfo->prizeGoods)==0) return $this->reMsg->re(0,'奖品不能为空');
            if($actInfo->prizeRule==null) return $this->reMsg->re(0,'规则不能为空');

            $prizePercent = $actInfo->prizeRule->percent;
            //获取中奖概率
            $arr10n = [10,20,30,40,50,60,70,80,90,100];
            if(!in_array($prizePercent,$arr10n)) return $this->reMsg->re(0,'请设置中奖概率！');

            //默认未中奖信息
            $insertData['party_id'] = $_user->party_id;
            $insertData['act_id'] = $act_id;
            $insertData['uid'] = $_user->id;
            $insertData['prize_goods_id'] = null;
            $insertData['prize_goods_name'] = null;
            $insertData['status'] = 0; //未中奖
            foreach ($actInfo->prizeGoods as $apKey=>$apVal){
                if($apVal->type==2){
                    $insertData['prize_goods_id'] = $apVal->id;
                    $insertData['prize_goods_name'] = $apVal->name;
                    break;
                }
            }

            //获取随机数值
            $randIndex = array_rand($arr10n);
            $randValue = $arr10n[$randIndex];

            //定义每个比例的抽奖数组
            $prizeNumArr = [];
            switch ($prizePercent){
                case 10:
                    $prizeNumArr = [10];
                    break;
                case 20:
                    $prizeNumArr = [10,20];
                    break;
                case 30:
                    $prizeNumArr = [10,20,30];
                    break;
                case 40:
                    $prizeNumArr = [10,20,30,40];
                    break;
                case 50:
                    $prizeNumArr = [10,20,30,40,50];
                    break;
                case 60:
                    $prizeNumArr = [10,20,30,40,50,60];
                    break;
                case 70:
                    $prizeNumArr = [10,20,30,40,50,60,70];
                    break;
                case 80:
                    $prizeNumArr = [10,20,30,40,50,60,70,80];
                    break;
                case 90:
                    $prizeNumArr = [10,20,30,40,50,60,70,80,90];
                    break;
                case 100:
                    $prizeNumArr = [10,20,30,40,50,60,70,80,90,100];
                    break;
                default:
                    break;
            }
            //判断是否中奖
            if(in_array($randValue,$prizeNumArr)){
                //表示抽中奖品
                //$lockAutoGetNum = 0;
                $lockValue = $this->redisPrefix.mt_rand();
                //抢锁操作
                if($this->lock($lockKey,$lockValue)) {
                    //设置锁过期时间
                    $this->redis->expire($lockKey,1);

                    //参与抽奖的商品
                    $chouGoods = [];

                    //获取本次活动的商品库（走到这儿表示可以中奖，就看是否还有商品库存），所以排除谢谢参与奖
                    $chouWhere = [
                        ['act_id','=',$act_id],
                        ['stock','>',0],
                        ['status','=',1],
                    ];
                    $chouWhereIn = [1];
                    $prizeGoodsList = ActPrizeGoods::where($chouWhere)
                        ->where($chouWhere)
                        ->whereIn('type',$chouWhereIn)
                        ->orderBy('sort')
                        ->get();
                    if($prizeGoodsList->isNotEmpty()){
                        //需要查看是否还有奖品库存，若没有则中奖状态还需改为 prizeStatus = 0
                        //先统计每个商品已经抽取多少量
                        $prizeJoinLog = ActPrizeJoin::where('act_id',$act_id)
                            ->whereIn('status',[1,2])
                            ->select('id','prize_goods_id',Db::raw("count(*) as ready_count"))
                            ->groupBy('prize_goods_id')
                            ->get();
                        $i = 0;
                        if($prizeJoinLog->isNotEmpty()){
                            foreach ($prizeGoodsList as $pKey=>$pVal){
                                $hasLog = false;
                                foreach ($prizeJoinLog as $jKey=>$jVal){
                                    if($pVal->id==$jVal->prize_goods_id){
                                        $hasLog = true;
                                        if($pVal->stock>$jVal->ready_count){
                                            $chouGoods[$i]['id'] = $pVal->id;
                                            $chouGoods[$i]['name'] = $pVal->name;
                                        }
                                    }
                                }
                                if(!$hasLog){
                                    $chouGoods[$i]['id'] = $pVal->id;
                                    $chouGoods[$i]['name'] = $pVal->name;
                                }
                                $i++;
                            }
                        }else{
                            //没有记录
                            foreach ($prizeGoodsList as $pKey=>$pVal){
                                $chouGoods[$i]['id'] = $pVal->id;
                                $chouGoods[$i++]['name'] = $pVal->name;
                            }
                        }
                    }
                    if(count($chouGoods)>0){
                        $chouIndex = array_rand($chouGoods);
                        $chouVal = $chouGoods[$chouIndex];
                        //中奖信息
                        $insertData['prize_goods_id'] = $chouVal['id'];
                        $insertData['prize_goods_name'] = $chouVal['name'];
                        $insertData['status'] = 1; //中奖
                    }
                    $insertRet = ActPrizeJoin::create($insertData);
                    $this->redis->del($lockKey); //取消锁
                }else{
                    return $this->reMsg->re(0,'当前参与人数较多！');
                }
            }else{
                //未中奖记录
                $insertRet = ActPrizeJoin::create($insertData);
            }
            //说明已经抽奖
            Act::where('id',$act_id)->increment('join_count',1); //参与抽奖人数+1

            //往活动主参与记录里面加入记录
            $actJoinData['act_id'] = $info->id;
            $actJoinData['act_type'] = $info->type;
            $actJoinData['title'] = $info->title;
            $actJoinData['photo'] = $info->photo;
            $actJoinData['uid'] = $_user->id;
            $actJoinData['party_id'] = $_user->party_id;
            ActJoin::create($actJoinData);

            //加积分
            $params = [
                'type'=> 7, //积分类型 type 1:学习 2:评论 4:支部活动点赞 5:答题 6:报名 7:抽奖 8:签到 9:问卷 10:支部信息更新
                'action' => 1, //action 1:加积分 2:减积分
                'uid' => $_user->id,  //用户id
                'party_id' => $_user->party_id  //支部id
            ];
            $this->makeIntegralLog($params);
            $this->redis->del($lockKey); //取消锁
            return $this->reMsg->re(1,'success',$insertRet);
        }catch (\Exception $exception){
            $this->redis->del($lockKey); //取消锁
            return $this->diyError->errorJson($exception);
        }
    }


}